package simulator;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;


import cartago.OPERATION;
import cartago.OpFeedbackParam;
import cartago.tools.GUIArtifact;
/*
		//exemplo de uso dos m�todos
		makeArtifact("myGrid","simulator.FildGrid"); //ari 
     	createGarbage(0, 11); //ari
     	goTo(1,11);	//ari
     	removeGarbage(11);	//ari
     	goToIncinerator(0);
     	
     	idRobos:
     		0:vassoura;
     		1:pano
     		2:vagao
     		3:Nao usando
 */
public class FildGrid extends GUIArtifact {
    
    protected InterfaceFrame frame;
    protected int numberOfRobs = 4;
    protected static int gridSize = 10;
    protected int escale = 40;
    protected int time_interval=200;
    protected int totalCoallition = 0;
    protected int[][] pos = new int[numberOfRobs][3];
    
    protected static ArrayList<Garbages> garbages = new ArrayList<Garbages>();
    

    
    protected void init(){
    	//inicializa o frame.
        frame = new InterfaceFrame(this);
        frame.setVisible(true);
        //inicializa todos os robos em uma posicoes (x,y) aleatoria.
        for(int i=0;i<numberOfRobs;i++){
        	pos[i][0]=(int)(Math.random()*(gridSize));
            pos[i][1]=(int)(Math.random()*(gridSize));
        }
        
        
    }
    // Robo de ID= idRobot vai para o slot do lixo de idGarbage
    @OPERATION void goToIncinerator(int idRobot){
    	if(idRobot>=numberOfRobs){
    		System.err.println("\tIdRobot("+idRobot+") maior que "+numberOfRobs);
    	}
    	else{
    		while(pos[idRobot][0]<(this.gridSize-1)){
    			pos[idRobot][0]++;
    			frame.repaint();
	    		try {
					Thread.sleep(time_interval);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
	    		
  		
	    	}
    		while(pos[idRobot][1]<(this.gridSize-1)){
    			pos[idRobot][1]++;
    			frame.repaint();
	    		try {
					Thread.sleep(time_interval);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
	    			    		
	    	}
	    }
    }
    // Robo de ID= idRobot vai para o slot do lixo de idGarbage
    @OPERATION void goToGarbage(int idRobot, int idGarbage){
    	if(idRobot>=numberOfRobs){
    		System.err.println("\tIdRobot("+idRobot+") maior que "+numberOfRobs);
    	}
    	else{
    		boolean find=false;
	    	for(int i=0;i<garbages.size();i++){	    		
	    		if(garbages.get(i).getId()==idGarbage){
	    			find=true;
	    			while(pos[idRobot][0]!=garbages.get(i).getX()){
	    				if(pos[idRobot][0]<garbages.get(i).getX()){
	    					pos[idRobot][0]++;
	    				}else{
	    					pos[idRobot][0]--;
	    				}
	    				frame.repaint();
	    				try {
							Thread.sleep(time_interval);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
	    				
	    			}
	    			while(pos[idRobot][1]!=garbages.get(i).getY()){
	    				if(pos[idRobot][1]<garbages.get(i).getY()){
	    					pos[idRobot][1]++;
	    				}else{
	    					pos[idRobot][1]--;
	    				}
	    				frame.repaint();
	    				try {
							Thread.sleep(time_interval);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
	    				
	    			}
	    			break;
	    		}
	    	}
	    	if(find==false){
	    		System.err.println("\tNao consegue andar porque nao achou o idGarbage="+idGarbage);
	    	}
	    }
    	
    }
    /*
     * Cria um lixo do tipo=type e ID=idGarbage em uma posicao (x,y) aleatoria
     * Type=0 -> lixo solido
     * Type=1 -> lixo liquido
     */
    @OPERATION void createGarbage(){
    	
    	int idGarbage=(int)(Math.random()*10000+10000);
    	boolean find=false;
	    for(int i=0;i<garbages.size();i++){
	    	if(garbages.get(i).getId()==idGarbage){
	    		find=true;
	    	}
	    }
	    if(find==false){
	    	int type = (int)(Math.random()*2);
		   	int x=(int)(Math.random()*(gridSize));
		   	int y=(int)(Math.random()*(gridSize));
		   	garbages.add(new Garbages(x,y,type, idGarbage));
		  
		   	System.out.println("\tlixo criado na pos("+x+","+y+"), type="+type+", idGarbage="+idGarbage);
		   	frame.repaint();
	    }else{
	    	System.err.println("\tLixo de idGarbage="+idGarbage+" nao criado pois o ID ja existe");
	    }
    }
    /*
     * 
     */
    @OPERATION void putIncinerator(int n){
    	frame.putGarbageIncinerator(n);
    }
    /*
     * Remove um lixo de ID=idGarbage
     */
    @OPERATION void removeGarbage(int idGarbage){
    	boolean find=false;
    	for(int i=0;i<garbages.size();i++){    		
    		if(garbages.get(i).getId()==idGarbage){
    			find=true;
    			System.out.println("\tlixo removido na pos("+garbages.get(i).getX()+","+garbages.get(i).getY()+"), type="+garbages.get(i).getType()+", idGarbage="+idGarbage);
    			garbages.remove(i);    			
    		}
    	}
    	if(find==false){
    		System.err.println("\tNao foi poss�vel remover o lixo de idGarbage="+idGarbage+". IdGarbage nao encontrado");
    	}
    	
    }
    /*
     * Retorna 0 se n existe lixo, caso contrario retorna o ID do lixo
     * 
     */
    @OPERATION void getidgar(OpFeedbackParam iDReturn){
        if(garbages.size()>0){
                iDReturn.set(garbages.get(0).idGarbage);
        }else{
                iDReturn.set(0);
        }
    }
    
    /*
     * Retorna o tipo do lixo 1
     * 
     */
    @OPERATION void gettypegar(OpFeedbackParam iDReturn){
        if(garbages.size()>0){
                iDReturn.set(garbages.get(0).type);
        }else{
                iDReturn.set(0);
        }
    }
   
    @OPERATION void sweepGarbage(int idGarbage){
    	boolean find=false;
    	for(int i=0;i<garbages.size();i++){
    		if(garbages.get(i).getId()==idGarbage){
    			find=true;
    			garbages.get(i).sweepedGarbage();
    		}
    		frame.repaint();
    		try {
				Thread.sleep(time_interval);
	
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    	}
    	if(find==false){
    		System.err.println("\tNao foi poss�vel varrer o lixo de idGarbage="+idGarbage+". IdGarbage nao encontrado");
    	}
    }
    @OPERATION void incTotalNumberCoallition(){
    	this.totalCoallition++;
    	//frame.repaint();
    }
    @OPERATION void incMyNumberCoallition(int idRob){
    	this.pos[idRob][2]++;
    	//frame.repaint();
    }
    @OPERATION void getDistance(int idRob, int idGarbage, OpFeedbackParam distance){
    	boolean find=false;
    	int dif_x=0;
    	int dif_y=0;    	
    	for(int i=0;i<garbages.size();i++){
    		if(garbages.get(i).getId()==idGarbage){
    			find=true;
    			dif_x=Math.abs(pos[idRob][0]-garbages.get(i).getX());
    			dif_y=Math.abs(pos[idRob][1]-garbages.get(i).getY());
    			int dist=(int)Math.sqrt(Math.pow(dif_x, 2)+Math.pow(dif_y, 2));
    			distance.set(dist);
    		}
    	}
    	if(find==false){
    		System.err.println("\tNao foi possivel localizar o lixo de idGarbage="+idGarbage+". IdGarbage nao encontrado");
    	}   	
    	
    	
    }
}